package main

import "fmt"

// 假设一开始我们提供了A对象，后期随着业务迭代，
// 又需要从A对象的基础之上衍生出不同的需求。如果有很多函数已经在线上调用了A对象，
// 此时再对A对象进行修改就比较麻烦，因为需要考虑兼容问题。还有更糟糕的情况，
// 你可能没有程序库的源代码， 从而无法对其进行修改。
// 此时就可以用一个适配器，它就像一个接口转换器，
// 调用方只需要调用这个适配器接口，而不需要关注其背后的实现，由适配器接口封装复杂的过程。

type Cm interface {
	getLength(float64) float64
}

type M interface {
	getLength(float64) float64
}

func NewM() M {
	return &getLengthM{}
}

type getLengthM struct{}

func (*getLengthM) getLength(cm float64) float64 {
	return cm / 10
}

func NewCm() Cm {
	return &getLengthCm{}
}

type getLengthCm struct{}

func (a *getLengthCm) getLength(m float64) float64 {
	return m * 10
}

type LengthAdapter interface {
	getLength(string, float64) float64
}

func NewLengthAdapter() LengthAdapter {
	return &getLengthAdapter{}
}

type getLengthAdapter struct{}

func (*getLengthAdapter) getLength(isType string, into float64) float64 {
	if isType == "cm" {
		return NewCm().getLength(into)
	} else {
		return NewM().getLength(into)
	}
}

func ExampleAdapter() {
	into := 10.5
	adapter := NewLengthAdapter().getLength("m", into)
	getLengthM := NewM().getLength(into)

	if adapter != getLengthM {
		fmt.Println("适配器模式测试失败")
	}
}
